#include "tcpsocket.h"
#include "debug.h"

#define LISTEN_SZ 10
// 创建tcp套接字， 并绑定ip和端口
int create_tcp_server_socket(const char *ip, unsigned short port) {
    struct sockaddr_in svr_addr;
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sfd == -1) {
        // perror("socket error");
        DEBUG_INFO("[error] Failed to socket : %s \n", strerror(errno));
        return -1;
    }

    bzero(&svr_addr, sizeof(svr_addr));
    svr_addr.sin_family = AF_INET;
    svr_addr.sin_port = htons(port);
    svr_addr.sin_addr.s_addr = inet_addr(ip);

    // 绑定
    if(bind(sfd, (struct sockaddr *)&svr_addr, sizeof(svr_addr)) == -1) {
        // perror("bind error");
        DEBUG_INFO("[error] Failed to bind : %s \n", strerror(errno));
        return -1;
    }

    int ret = listen(sfd, LISTEN_SZ);
    if (ret == -1) {
        // perror("listen error");
        DEBUG_INFO("[error] Failed to listen : %s \n", strerror(errno));
        return -1;
    }
    return sfd;
}
// 封装tcp socket 
int create_tcp_client_socket(const char *ip, unsigned short port) {
    struct sockaddr_in cli_addr;
    int cfd = socket(AF_INET, SOCK_STREAM, 0);
    if (cfd == -1) {
        // perror("socket error");
        DEBUG_INFO("[error] Failed to socket : %s \n", strerror(errno));
        return -1;
    }

    bzero(&cli_addr, sizeof(cli_addr));
    cli_addr.sin_family = AF_INET;
    cli_addr.sin_port = htons(port);
    cli_addr.sin_addr.s_addr = inet_addr(ip);

    int ret = connect(cfd, (struct sockaddr *)&cli_addr, sizeof(struct socketaddr));
    if (ret == -1) {
        DEBUG_INFO("[error] Failed to connect : %s \n", strerror(errno));
        return -1;
    }
    DEBUG_INFO("[INFO]: Connect %s  successed.\n", ip);
   
    return cfd;
}

// 服务端accept
int wait_for_connect(int sfd, struct sockaddr_in *cli_addr) {
    int cfd;
    socklen_t len = sizeof(struct sockaddr_in);
    cfd = accept(sfd, (struct sockaddr *)cli_addr, &len);
    if (cfd == -1) {
        DEBUG_INFO("[error] Failed to accept : %s \n", strerror(errno));
        return -1;
    }
    return cfd;
}
// 打印接收端口

void show_tcp_network_address(struct sockaddr_in *sockaddr) {
    printf("ip: %s\n", inet_ntoa(sockaddr->sin_addr));
    printf("port: %d\n", ntohs(sockaddr->sin_port);
}
// 发送
ssize_t tcp_send_pack(int sockfd, const void * buf, size_t len) {
    return send(sockfd, buf, len, 0);
}
// 接收
ssize_t tcp_recv_pack(int sockfd, void * buf, size_t len) {
    return recv(sockfd, buf, len, 0);
}